package pkg.chemdrm;

import java.util.LinkedList;

import org.anddev.andengine.entity.layer.tiled.tmx.TMXLayer;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXObject;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXObjectGroup;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXObjectGroupProperty;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXObjectProperty;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXTile;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXTileProperty;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXTiledMap;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXTiledMapProperty;
import org.anddev.andengine.entity.shape.IShape;
import org.anddev.andengine.entity.sprite.Sprite;
import org.anddev.andengine.entity.layer.tiled.tmx.util.constants.TMXConstants;

public class Map {
	private GameScene mGameScene;
	private TMXTiledMap mTiles;
	private TMXObjectGroup mCollisionLayer;
	private ResourceHandler mResourceHandler;
	private AIHandler mAIHandler;
	
	private int mStartX;
	private int mStartY;
	
	public LinkedList<FogEntity> mFogList = new LinkedList<FogEntity>();
	public LinkedList<ZRegion> mZRegionList = new LinkedList<ZRegion>();
	public LinkedList<ZRegion> mPitsList = new LinkedList<ZRegion>();
	public LinkedList<ScriptEntity> mScriptList = new LinkedList<ScriptEntity>();
	public LinkedList<AIRegion> mDarknessList = new LinkedList<AIRegion>();
	public LinkedList<DoorSprite> mDoorList = new LinkedList<DoorSprite>();
	public EntityBoss mBoss;
	public AIRegion mEnd; 
	public boolean mDeathFlag = false;
	
	public Map(AIHandler pAIHandler, GameScene pGameScene, ResourceHandler pResourceHandler)
	{
		mGameScene = pGameScene;
		mResourceHandler = pResourceHandler;
	
		mAIHandler = pAIHandler;
		
		
		// TODO: remove this, and do something more 'fficial.
		loadMap("Maps/TheLevel.tmx");
		setColor(202f/255f, 171f/255f, 204f/255f);
	}
	
	public void setColor(float r, float g, float b)
	{
		TMXLayer t = mTiles.getTMXLayers().get(0);
		t.setAlpha(255f/255f);
		t.setColor(r, g, b);
		
		t = mTiles.getTMXLayers().get(1);
		t.setAlpha(255f/255f);
		t.setColor(r, g, b);
	}
	
	public boolean checkDoorCollision(IShape pShape)
	{
		float Ax1 = pShape.getX();
		float Ay1 = pShape.getY();
		float Ax2 = pShape.getX() + pShape.getWidth();
		float Ay2 = pShape.getY() + pShape.getHeight();
		
		
		for(DoorSprite z : mDoorList)
		{
			float Bx1 = z.getX();
			float By1 = z.getY();
			float Bx2 = z.getX() + z.getWidth();
			float By2 = z.getY() + z.getHeight();
			
			if (Ax1 < Bx2 && Ax2 > Bx1 && Ay1 < By2 && Ay2 > By1)
			{
				if(!z.mDeath)
				{
					return true;
				}
			}
		}
		
		return false;
				
	}
	
	public boolean checkCollision(IShape pShape)
	{
		float Ax1 = pShape.getX();
		float Ay1 = pShape.getY();
		float Ax2 = pShape.getX() + pShape.getWidth();
		float Ay2 = pShape.getY() + pShape.getHeight();
		
		for(TMXObject o : mCollisionLayer.getTMXObjects())
		{
			float Bx1 = o.getX();
			float By1 = o.getY();
			float Bx2 = o.getX() + o.getWidth();
			float By2 = o.getY() + o.getHeight();
			
			if (Ax1 < Bx2 && Ax2 > Bx1 && Ay1 < By2 && Ay2 > By1)
				return true;
		}
		
		return checkDoorCollision(pShape);
	}
	
	public void loadMap(final String pFilename)
	{
		// load stuff here
		mTiles = mResourceHandler.getMap(pFilename);
		//mTiles.getTMXObjectGroups()
		
		// TODO: for now, add all layers, in the future' well need to do some information gathering before we do this (not all layers will be visible).
		for(TMXObjectGroup g : mTiles.getTMXObjectGroups())
		{
			
			
			if(g.getName().equals("CollisionMap"))
			{
				mCollisionLayer = g;
			}
			else if(g.getName().equals("Fog"))
			{
				for(TMXObject o : g.getTMXObjects())
				{
					float x = o.getX(), y = o.getY(), w = o.getWidth(), h = o.getHeight();
				
					for(int i = 0; i < 64; i++)
						mFogList.add(new FogEntity(new AIRegion(x,y,w,h), (float)Math.random()*w + x, (float)(Math.random()*h + y), 128, 128, mResourceHandler.getRegion("Fog")));
				}
			}
			else if(g.getName().equals("zFall"))
			{
				for(TMXObject o : g.getTMXObjects())
				{
					float x = o.getX(), y = o.getY(), w = o.getWidth(), h = o.getHeight();
					int z = 0;
					z = Integer.parseInt(o.getTMXObjectProperties().get(0).getValue());
					System.err.println("ZBlock: " + x + " " + y + " " + w + " " + h + " " + z);
					
					mZRegionList.add(new ZRegion(new AIRegion(x, y, w, h), z));
				}
				
			}
			else if(g.getName().equals("Pits"))
			{
				for(TMXObject o : g.getTMXObjects())
				{
					float x = o.getX(), y = o.getY(), w = o.getWidth(), h = o.getHeight();
					int z = 0;
					//z = Integer.parseInt(o.getTMXObjectProperties().get(0).getValue());
					System.err.println("Pit: " + x + " " + y + " " + w + " " + h + " " + z);
					
					mPitsList.add(new ZRegion(new AIRegion(x, y, w, h), 0));
				}
			}
			else if(g.getName().equals("SpawnIntro"))
			{
				for(TMXObject o : g.getTMXObjects())
				{
					float x = o.getX(), y = o.getY(), w = o.getWidth(), h = o.getHeight();
					int z = 1;
					mScriptList.add(new ScriptEntity(new AIRegion(x,y,w,h), z));
				}
			}
			else if(g.getName().equals("RobotIntro"))
			{
				for(TMXObject o : g.getTMXObjects())
				{
					float x = o.getX(), y = o.getY(), w = o.getWidth(), h = o.getHeight();
					int z = 2;
					mScriptList.add(new ScriptEntity(new AIRegion(x,y,w,h), z));
				}
			}
			else if(g.getName().equals("IronDoorIntro"))
			{
				for(TMXObject o : g.getTMXObjects())
				{
					float x = o.getX(), y = o.getY(), w = o.getWidth(), h = o.getHeight();
					int z = 3;
					mScriptList.add(new ScriptEntity(new AIRegion(x,y,w,h), z));
				}
			}
			else if(g.getName().equals("SlimeIntro"))
			{
				for(TMXObject o : g.getTMXObjects())
				{
					float x = o.getX(), y = o.getY(), w = o.getWidth(), h = o.getHeight();
					int z = 4;
					mScriptList.add(new ScriptEntity(new AIRegion(x,y,w,h), z));
				}
			}
			else if(g.getName().equals("RampIntro"))
			{
				for(TMXObject o : g.getTMXObjects())
				{
					float x = o.getX(), y = o.getY(), w = o.getWidth(), h = o.getHeight();
					int z = 5;
					mScriptList.add(new ScriptEntity(new AIRegion(x,y,w,h), z));
				}
			}
			else if(g.getName().equals("DarknessIntro"))
			{
				for(TMXObject o : g.getTMXObjects())
				{
					float x = o.getX(), y = o.getY(), w = o.getWidth(), h = o.getHeight();
					int z = 6;
					mScriptList.add(new ScriptEntity(new AIRegion(x,y,w,h), z));
				}
			}
			else if(g.getName().equals("FireballIntro"))
			{
				for(TMXObject o : g.getTMXObjects())
				{
					float x = o.getX(), y = o.getY(), w = o.getWidth(), h = o.getHeight();
					int z = 7;
					mScriptList.add(new ScriptEntity(new AIRegion(x,y,w,h), z));
				}
			}
			else if(g.getName().equals("FogIntro"))
			{
				for(TMXObject o : g.getTMXObjects())
				{
					float x = o.getX(), y = o.getY(), w = o.getWidth(), h = o.getHeight();
					int z = 8;
					mScriptList.add(new ScriptEntity(new AIRegion(x,y,w,h), z));
				}
			}
			else if(g.getName().equals("SlugIntro"))
			{
				for(TMXObject o : g.getTMXObjects())
				{
					float x = o.getX(), y = o.getY(), w = o.getWidth(), h = o.getHeight();
					int z = 9;
					mScriptList.add(new ScriptEntity(new AIRegion(x,y,w,h), z));
				}
			}
			else if(g.getName().equals("BossIntro"))
			{
				for(TMXObject o : g.getTMXObjects())
				{
					float x = o.getX(), y = o.getY(), w = o.getWidth(), h = o.getHeight();
					int z = 10;
					mScriptList.add(new ScriptEntity(new AIRegion(x,y,w,h), z));
				}
			}
			else if(g.getName().equals("Darkness"))
			{
				System.err.println("There are " + g.getTMXObjects().size() + " darkness objects.");
				for(TMXObject o : g.getTMXObjects())
				{
					float x = o.getX(), y = o.getY(), w = o.getWidth(), h = o.getHeight();
					
					mDarknessList.add(new AIRegion(x, y, w, h));	
				}
			}
			else if(g.getName().equals("IronDoor"))
			{
				for(TMXObject o : g.getTMXObjects())
				{
					float x = o.getX(), y = o.getY(), w = o.getWidth(), h = o.getHeight();
					
					mDoorList.add(new DoorSprite(new AIRegion(x, y, w, h), mResourceHandler.getAnimatedRegion("Door").deepCopy()));	
				}
			}
			else if(g.getName().equals("Boss"))
			{
				for(TMXObject o : g.getTMXObjects())
				{
					float x = o.getX(), y = o.getY(), w = o.getWidth(), h = o.getHeight();
					
					mBoss = new EntityBoss(x, y, w, h, mResourceHandler.getRegion("Gnome"));
					
				}
			}
			else if(g.getName().equals("End"))
			{
				for(TMXObject o : g.getTMXObjects())
				{
					float x = o.getX(), y = o.getY(), w = o.getWidth(), h = o.getHeight();
					
					mEnd = new AIRegion(x, y, w, h);
					
				}
			}
			else
			{
				String s = g.getName();
	
				if(s.equals("Robot"))
				{
					System.err.println("There are " + g.getTMXObjects().size() + " robot regions.");
					for(TMXObject o : g.getTMXObjects())
					{
						float x = o.getX(), y = o.getY(), w = o.getWidth(), h = o.getHeight();
					
	
						mAIHandler.addAI(new AIPlayer(new AIRegion(x, y, w, h), (x+(x+w))/2, (y+(h+y))/2, 96, 107, mResourceHandler.getAnimatedRegion("Robot"), "Robot"));

					}
					
					
				}
				else if(s.equals("Slime"))
				{
					System.err.println("There are " + g.getTMXObjects().size() + " slime regions.");
					for(TMXObject o : g.getTMXObjects())
					{
						float x = o.getX(), y = o.getY(), w = o.getWidth(), h = o.getHeight();
					
	
						mAIHandler.addAI(new AIPlayer(new AIRegion(x, y, w, h), (x+(x+w))/2, (y+(h+y))/2, 32, 32, mResourceHandler.getAnimatedRegion("Slime"), "Slime"));

					}
					
					
				}
				else if(s.equals("Fireball"))
				{
					System.err.println("There are " + g.getTMXObjects().size() + " fireball regions.");
					for(TMXObject o : g.getTMXObjects())
					{
						float x = o.getX(), y = o.getY(), w = o.getWidth(), h = o.getHeight();
					
						AIPlayer p = new AIPlayer(new AIRegion(x, y, w, h), (x+(x+w))/2, (y+(h+y))/2, 57, 57, mResourceHandler.getAnimatedRegion("Fireball"), "Fireball", mResourceHandler);
	
						p.setTorch(true);
						mAIHandler.addAI(p);
						
					}
					
					
				}else if(s.equals("Slug"))
				{
					System.err.println("There are " + g.getTMXObjects().size() + " slug regions.");
					for(TMXObject o : g.getTMXObjects())
					{
						float x = o.getX(), y = o.getY(), w = o.getWidth(), h = o.getHeight();
					
	
						mAIHandler.addAI(new AIPlayer(new AIRegion(x, y, w, h), (x+(x+w))/2, (y+(h+y))/2, 116, 100, mResourceHandler.getAnimatedRegion("Slug"), "Slug"));

					}
					
					
				}
				
				else
				{
					System.err.println(s);
				}
				
			}
			
		}
		for(TMXLayer p : mTiles.getTMXLayers())
		{
			mGameScene.attachChild(p);

		}
		parseMap();
	}
	
	private void parseMap()
	{
		// TODO: Gather appropriate information from map. This includes declaring regions, particle systems, paths, enemies, and starting location for player.
		
		for(TMXTiledMapProperty p : mTiles.getTMXTiledMapProperties())
		{
			System.out.println(p.getName() + " " + p.getValue());
			if(p.getName().equals("PlayerStart"))
			{
				parseStartPosition(p.getValue());
			}
		}
	}
	
	// I assume we wrote everything correctly!
	private void parseStartPosition(String pValue)
	{
		String[] args = pValue.split("[, ]+");
		mStartX = Integer.parseInt(args[0])*mTiles.getTileWidth();
		mStartY = Integer.parseInt(args[1])*mTiles.getTileHeight();
		
	}
	
	public int getStartX()
	{
		return mStartX;
	}
	
	public int getStartY()
	{
		return mStartY;
	}
	
	public float getMapWidth()
	{
		return mTiles.getTileWidth()*mTiles.getTileColumns();
		
	}
	
	public float getMapHeight()
	{
		return mTiles.getTileHeight()*mTiles.getTileRows();
	}

}
